package com.androidgame.fx.impl;

import android.app.Activity;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.os.Bundle;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.util.DisplayMetrics;
import android.view.Window;
import android.view.WindowManager;

import com.androidgame.fx.Audio;
import com.androidgame.fx.FileIO;
import com.androidgame.fx.Game;
import com.androidgame.fx.GameTime;
import com.androidgame.fx.Graphics;
import com.androidgame.fx.Input;
import com.androidgame.fx.Screen;
import com.androidgame.fx.ScreenConfig;

public abstract class AndroidGame extends Activity implements Game {
	
	protected AndroidFastRenderView	renderView;
	protected Graphics 		graphics;
	protected Audio 		audio;
	protected Input 		input;
	protected FileIO 		fileIO;
	protected Screen 		screen;
	protected ScreenConfig 	screenConfig;
	protected WakeLock 		wakeLock;
	protected GameTime		gameTime;
	
    @Override // 액티비티가 최초 시작할 때 호출됩니다.
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // 타이틀바를 없애고 전체화면으로 설정합니다.
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

        // 이미지를 그려넣을 프레임 버퍼의 크기를 결정하고 버퍼를 생성합니다.
        boolean isLandscape = getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE;
        int frameBufferWidth = isLandscape ? 1280 : 720;
        int frameBufferHeight = isLandscape ? 720 : 1280;
        Bitmap frameBuffer = Bitmap.createBitmap(frameBufferWidth, frameBufferHeight, Config.RGB_565);
        
        // 기기의 화면 크기를 얻어옵니다.
		DisplayMetrics metrics = new DisplayMetrics();
		getWindowManager().getDefaultDisplay().getMetrics(metrics);
		int width = metrics.widthPixels;
		int height = metrics.heightPixels;
        
		// 프레임 버퍼와 기기 화면의 크기 비율을 계산합니다.
        float scaleX = (float) frameBufferWidth / width;
        float scaleY = (float) frameBufferHeight / height;

        // 게임의 자원들을 생성합니다.
        renderView = new AndroidFastRenderView(this, frameBuffer);
        graphics = new AndroidGraphics(getAssets(), getResources(), frameBuffer);
        fileIO = new AndroidFileIO(this);
        audio = new AndroidAudio(this);
        input = new AndroidInput(this, renderView, scaleX, scaleY);
        gameTime = new GameTime();
        screenConfig = new ScreenConfig(width, height, frameBufferWidth, frameBufferHeight);
        screen = getStartScreen();
        setContentView(renderView);
        
        // 깨어있기 락을 얻어옵니다.
        PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
        wakeLock = powerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, "GLGame");
    }
 
    @Override // 액티비티가 재개할 때 호출됩니다.
    public void onResume() {
        super.onResume();
        // 깨어있기 락을 활성화 시킵니다.
        wakeLock.acquire();
        screen.resume();
        renderView.resume();
    }

    @Override // 액티비티가 일시 정지될 때 호출됩니다.
    public void onPause() {
        super.onPause();
        // 깨어있기 락을 비활성화 시킵니다.
        wakeLock.release();
        // 현재 화면에 대한 일시정지 처리를 합니다.
        screen.pause();
        // 뷰에 대한 일시정지 처리를 합니다.
        renderView.pause();

        if (isFinishing())
            screen.dispose();
    }

    @Override
    public Input getInput() {
        return input;
    }

    @Override
    public FileIO getFileIO() {
        return fileIO;
    }

    @Override
    public Graphics getGraphics() {
        return graphics;
    }

    @Override
    public Audio getAudio() {
        return audio;
    }

    @Override
    public void setScreen(Screen screen) {
        if (screen == null)
            throw new IllegalArgumentException("Screen must not be null");

        this.screen.pause();
        this.screen.dispose();
        screen.resume();
        screen.update(0);
        this.screen = screen;
    }
    
    @Override
    public Screen getCurrentScreen() {
        return screen;
    }

    @Override
    public GameTime getGameTime() {
    	return gameTime;
    }
    
    @Override
    public void resetScreenConfig(int width, int height) {
		int frameBufferWidth = width;
		int frameBufferHeight = height;
		Bitmap frameBuffer = Bitmap.createBitmap(frameBufferWidth,
				frameBufferHeight, Config.RGB_565);
		
		// 기기의 화면 크기를 얻어옵니다.
		DisplayMetrics metrics = new DisplayMetrics();
		getWindowManager().getDefaultDisplay().getMetrics(metrics);
		
		// 프레임 버퍼와 기기 화면의 크기 비율을 계산합니다.
        float scaleX = (float) frameBufferWidth / metrics.widthPixels;
        float scaleY = (float) frameBufferHeight / metrics.heightPixels;
        
		// 게임의 자원들을 생성합니다.
		renderView.setFrameBuffer(frameBuffer);
		graphics.setFrameBuffer(frameBuffer);
		input.setScale(scaleX, scaleY);
		screenConfig.setConfig(metrics.widthPixels, metrics.heightPixels, frameBufferWidth, frameBufferHeight);  	
    }
}